package com.lmm.rpc.core.codec;

import com.lmm.rpc.core.client.protocol.MessageHeader;
import com.lmm.rpc.core.client.protocol.MessageProtocol;
import com.lmm.rpc.core.serialization.Serialization;
import com.lmm.rpc.core.serialization.SerializationFactory;
import com.lmm.rpc.core.serialization.SerializationTypeEnum;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;

import java.nio.charset.StandardCharsets;

/**
 * 编码器
 *
 *
 *1byte == 1个字 == 8位二进制
 *      *  +---------------------------------------------------------------+
 *      *  | 魔数 2byte | 协议版本号 1byte | 序列化算法 1byte | 报文类型 1byte|
 *      *  +---------------------------------------------------------------+
 *      *  | 状态 1byte |        消息 ID 8byte     |      数据长度 4byte    |
 *      *  +---------------------------------------------------------------+
 *      *  |                   数据内容 （长度不定）                         |
 *      *  +---------------------------------------------------------------+
 *
 *      消息  to byte
 * */
public class DefaultEncoder<T> extends MessageToByteEncoder<MessageProtocol<T>> {
    @Override
    protected void encode(ChannelHandlerContext channelHandlerContext, MessageProtocol<T> messageProtocol, ByteBuf byteBuf) throws Exception {

        //处理请求头
        MessageHeader header = messageProtocol.getHeader();
        byteBuf.writeShort(header.getMagic());
        byteBuf.writeByte(header.getVersion());
        byteBuf.writeByte(header.getSerialization());
        byteBuf.writeByte(header.getMsgType());
        byteBuf.writeByte(header.getStatus());
        byteBuf.writeLong(header.getRequestId());
//        byteBuf.writeCharSequence(header.getRequestId(), StandardCharsets.UTF_8);

        //处理消息体
        Serialization rpcSerialization = SerializationFactory.getRpcSerialization(SerializationTypeEnum.parseByType(header.getSerialization()));
        byte[] data = rpcSerialization.serialize(messageProtocol.getBody());
        //写入数据的长度
        byteBuf.writeInt(data.length);
        byteBuf.writeBytes(data);
    }
}
